/*
 *  PPXMLReader.m
 *  PPXMLTest
 *
 *  Created by Jacob Basham on 2/1/07.
 *  Copyright 2007, PaperPigeons.net
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without 
 *  modification, are permitted provided that the following conditions 
 *  are met:
 *  1. Redistributions of source code must retain the above copyright 
 *     notice, this list of conditions and the following disclaimer.
 *	2. Redistributions in binary form must reproduce the above copyright 
 *	   notice, this list of conditions and the following disclaimer in 
 *	   the documentation and/or other materials provided with the distribution.
 *	3. Neither the name of PaperPigeons.net nor the names of its contributors 
 *	   may be used to endorse or promote products derived from this software 
 *	   without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 *	LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 *	FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 *	COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 *	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 *	BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 *	CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 *	LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 *	IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 *	POSSIBILITY OF SUCH DAMAGE.
 */

#import "PPXMLReader.h"


@implementation PPXMLReader

+ (id)readerWithFile:(NSString *)path delegate:(id)delegate
{
	id this = [[super alloc] init];
	[this setPath:path];
	[this setDelegate:delegate];
	return this;
}

+ (id)readerWithXMLData:(NSData *)data delegate:(id)delegate
{
	return nil;
}

+ (id)readerWithXMLDocument:(NSXMLDocument *)document delegate:(id)delegate
{
	return nil;
}

- (id)init
{
	if (self = [super init]) {
		_method = @selector(actionFromReader:);
	}
	return self;
}

- (NSString *)path
{
	return _path;
}

- (void)setPath:(NSString *)path
{
	[path retain];
	[_path release];
	_path = path;
}

- (id)delegate
{
	return _delegate;
}

- (void)setDelegate:(id)delegate
{
	[delegate retain];
	[_delegate release];
	_delegate = delegate;
	// parser releases delegate upon completion of run loop
}

#pragma mark START_LIBXML2_WRAPPERS

- (void)read
{
	const char * path = [_path cStringUsingEncoding:NSUTF8StringEncoding];
	_reader = xmlNewTextReaderFilename(path);
	if (_reader) {
		
		_ret = xmlTextReaderRead(_reader);
		while (_ret == 1) {
			if ([_delegate respondsToSelector:_method]) {
				objc_msgSend(_delegate, _method, self);
			}
			_ret = xmlTextReaderRead(_reader);
		}
		xmlFreeTextReader(_reader);
		[_delegate release];
		if (_ret != 0) {
			// TODO set error
			NSLog(@"A parsing error happened");
		}
	} else {
		// TODO set error
		NSLog(@"Something bad happened");
	}
}

- (int)numberAttributes
{
	if (_reader) {
		return xmlTextReaderAttributeCount(_reader);
	}
	return -1;
}

- (int)depth
{
	if (_reader)
		return xmlTextReaderDepth(_reader);
	return -1;
}

- (BOOL)hasAttributes
{
	if (_reader) {
		return xmlTextReaderHasAttributes(_reader);
	}
	return NO;
}

- (BOOL)hasValue
{
	if (_reader) {
		return xmlTextReaderHasValue(_reader);
	}
	return NO;
}

- (BOOL)isDefault
{
	if (_reader) {
		return xmlTextReaderIsDefault(_reader);
	}
	return NO;
}

- (BOOL)isEmptyElement
{
	if (_reader) {
		return xmlTextReaderIsEmptyElement(_reader);
	}
	return NO;
}

- (int)nodeType
{
	if (_reader) {
		return xmlTextReaderNodeType(_reader);
	}
	return -1;
}

- (int)quoteChar
{
	if (_reader) {
		return xmlTextReaderQuoteChar(_reader);
	}
	return -1;
}

- (int)readState
{
	// TODO does readers existence need to be caught?
	return xmlTextReaderReadState(_reader);
}

- (BOOL)isNamespaceDecl
{
	if (_reader) {
		return xmlTextReaderIsNamespaceDecl(_reader);
	}
	return NO;
}

- (NSString *)baseURI
{
	if (_reader) {
		return [NSString stringWithCString:(const char *)xmlTextReaderConstBaseUri(_reader)
							encoding:NSUTF8StringEncoding];
	}
	return nil;
}

- (NSString *)localName
{
	if (_reader) {
		return [NSString stringWithCString:(const char *)xmlTextReaderConstLocalName(_reader)
							encoding:NSUTF8StringEncoding];
	}
	return nil;
}

- (NSString *)name
{
	if (_reader) {
		return [NSString stringWithCString:(const char *)xmlTextReaderConstName(_reader)
							encoding:NSUTF8StringEncoding];
	}
	return nil;
}

- (NSString *)namespaceURI
{
	if (_reader) {
		return [NSString stringWithCString:(const char *)xmlTextReaderConstNamespaceUri(_reader)
							encoding:NSUTF8StringEncoding];
	}
	return nil;
}

- (NSString *)prefix
{
	if (_reader) {
		return [NSString stringWithCString:(const char *)xmlTextReaderConstPrefix(_reader)
							encoding:NSUTF8StringEncoding];
	}
	return nil;
}

- (NSString *)XMLLang
{
	if (_reader) {
		return [NSString stringWithCString:(const char *)xmlTextReaderConstXmlLang(_reader)
							encoding:NSUTF8StringEncoding];
	}
	return nil;
}

- (NSString *)characters
{
	if (_reader) {
		return [NSString stringWithCString:(const char *)xmlTextReaderConstValue(_reader)
							encoding:NSUTF8StringEncoding];
	}
	return nil;
}

- (NSString *)XMLVersion
{
	if (_reader) {
		return [NSString stringWithCString:(const char *)xmlTextReaderConstXmlVersion(_reader)
							encoding:NSUTF8StringEncoding];
	}
	return nil;
}

#pragma mark END_LIBXML2_WRAPPERS

#pragma mark START_PIGEONS_HELPERS

- (BOOL)isStartElementEqualToString:(NSString *)string
{
	if (xmlTextReaderNodeType(_reader) == XML_READER_TYPE_ELEMENT)
		if ([[self name] isEqualToString:string])
			return YES;
	return NO;
}

- (NSString *)getAttribute:(NSString *)attribute
{
	if (_reader) {
		const char * attrKey = [attribute cStringUsingEncoding:NSUTF8StringEncoding];
		return [NSString stringWithCString:xmlTextReaderGetAttribute(_reader, attrKey)
							encoding:NSUTF8StringEncoding];
	}
	return nil;
}

- (BOOL)isCharacterData
{
	if (xmlTextReaderNodeType(_reader) == XML_READER_TYPE_TEXT)
		return YES;
	return NO;
}

- (BOOL)isEndElementEqualToString:(NSString *)string
{
	if (xmlTextReaderNodeType(_reader) == XML_READER_TYPE_END_ELEMENT)
		if ([[self name] isEqualToString:string])
			return YES;
	return NO;
}

#pragma mark END_PIGEONS_HELPERS

@end
